import { REPAYMENT_TYPE } from './constants';
// 房贷计算结果
export interface MonthlyPaymentDetail {
  month: number;
  principal: number;
  interest: number;
  remainingPrincipal: number;
}
export interface MortgageResult {
  mortgageTotal: number;
  interestTotal: number;
  years: number;
  repaymentType: number;
  monthlyPaymentDetail: MonthlyPaymentDetail[];
}

/**
 * 计算等额本金还款
 * @param principal 贷款本金
 * @param monthlyInterestRate 月利率
 * @param totalMonths 还款总月数
 * @returns 还款详情
 */
function calculateEqualPrincipal(
  principal: number,
  monthlyInterestRate: number,
  totalMonths: number,
): {
  monthlyPaymentDetail: MonthlyPaymentDetail[];
  mortgageTotal: number;
  interestTotal: number;
} {
  const monthlyPrincipal = principal / totalMonths;
  let remainingPrincipal = principal;
  let mortgageTotal = 0;
  let interestTotal = 0;
  const monthlyPaymentDetail: MonthlyPaymentDetail[] = [];

  for (let month = 1; month <= totalMonths; month++) {
    const interest = remainingPrincipal * monthlyInterestRate;
    const payment = monthlyPrincipal + interest;
    remainingPrincipal -= monthlyPrincipal;

    monthlyPaymentDetail.push({
      month,
      principal: monthlyPrincipal,
      interest,
      remainingPrincipal,
    });

    mortgageTotal += payment;
    interestTotal += interest;
  }

  return { monthlyPaymentDetail, mortgageTotal, interestTotal };
}

/**
 * 计算等额本息还款
 * @param principal 贷款本金
 * @param monthlyInterestRate 月利率
 * @param totalMonths 还款总月数
 * @returns 还款详情
 */
function calculateEqualInstallment(
  principal: number,
  monthlyInterestRate: number,
  totalMonths: number,
): {
  monthlyPaymentDetail: MonthlyPaymentDetail[];
  mortgageTotal: number;
  interestTotal: number;
} {
  const monthlyPayment =
    (principal * monthlyInterestRate * Math.pow(1 + monthlyInterestRate, totalMonths)) /
    (Math.pow(1 + monthlyInterestRate, totalMonths) - 1);
  let remainingPrincipal = principal;
  let mortgageTotal = 0;
  let interestTotal = 0;
  const monthlyPaymentDetail: MonthlyPaymentDetail[] = [];

  for (let month = 1; month <= totalMonths; month++) {
    const interest = remainingPrincipal * monthlyInterestRate;
    const principalPaid = monthlyPayment - interest;
    remainingPrincipal -= principalPaid;

    monthlyPaymentDetail.push({
      month,
      principal: principalPaid,
      interest,
      remainingPrincipal,
    });

    mortgageTotal += monthlyPayment;
    interestTotal += interest;
  }

  return { monthlyPaymentDetail, mortgageTotal, interestTotal };
}

/**
 * 计算房贷月供
 * @param principal 贷款本金
 * @param interestRate 年利率
 * @param years 贷款年限
 * @param repayment 还款方式 0:等额本金 1:等额本息
 */
export function calculateMortgageRate(
  principal: number,
  interestRate: number,
  years: number,
  repayment: number,
): MortgageResult {
  const monthlyInterestRate = interestRate / 12 / 100;
  const totalMonths = years * 12;

  const { monthlyPaymentDetail, mortgageTotal, interestTotal } =
    repayment === REPAYMENT_TYPE.EQUAL_PRINCIPAL
      ? calculateEqualPrincipal(principal, monthlyInterestRate, totalMonths)
      : calculateEqualInstallment(principal, monthlyInterestRate, totalMonths);

  return {
    mortgageTotal,
    interestTotal,
    years,
    repaymentType: repayment,
    monthlyPaymentDetail,
  };
}
